package com.flyco.modules.stm.controller;

import java.text.DecimalFormat;
import java.util.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.stream.Collectors;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.flyco.common.api.vo.Result;
import com.flyco.common.system.query.QueryGenerator;
import com.flyco.common.aspect.annotation.AutoLog;
import com.flyco.common.system.vo.LoginUser;
import com.flyco.common.util.oConvertUtils;
import com.flyco.modules.pms.entity.PmsProduct;
import com.flyco.modules.pms.service.IPmsProductService;
import com.flyco.modules.stm.entity.StmChannelInfo;
import com.flyco.modules.stm.entity.StmChannelPrice;
import com.flyco.modules.stm.entity.StmChannelPriceExcel;
import com.flyco.modules.stm.entity.StmStoreInfo;
import com.flyco.modules.stm.model.StmStoreInfoExcel;
import com.flyco.modules.stm.service.IStmChannelInfoService;
import com.flyco.modules.stm.service.IStmChannelPriceService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyco.modules.stm.service.IStmStoreInfoService;
import lombok.extern.slf4j.Slf4j;
import com.flyco.common.system.base.controller.BaseController;
import com.flyco.poi.excel.ExcelImportUtil;
import com.flyco.poi.excel.def.NormalExcelConstants;
import com.flyco.poi.excel.entity.ExportParams;
import com.flyco.poi.excel.entity.ImportParams;
import com.flyco.poi.excel.view.EntityExcelView;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @Description: 经销商价格表
 * @Author: flyco
 * @Date: 2023-08-07
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "经销商价格表")
@RestController
@RequestMapping("/f/stm/stmChannelPrice")
public class StmChannelPriceController extends BaseController<StmChannelPrice, IStmChannelPriceService> {
    @Autowired
    private IStmChannelPriceService stmChannelPriceService;
    @Autowired
    private IPmsProductService pmsProductService;
    @Autowired
    private IStmChannelInfoService stmChannelInfoService;
    @Autowired
    private IPmsProductService productService;
    @Autowired
    private IStmStoreInfoService storeInfoService;

    /**
     * 分页列表查询
     *
     * @param stmChannelPrice
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "经销商价格表-分页列表查询")
    @ApiOperation(value = "经销商价格表-分页列表查询", notes = "经销商价格表-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(StmChannelPrice stmChannelPrice,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        String channelId = stmChannelPrice.getChannelId();
        String storeId = stmChannelPrice.getStoreId();
        StmStoreInfo storeInfo = storeInfoService.getByStoreId(Long.valueOf(storeId));
        stmChannelPrice.setPartnerId(storeInfo.getPartnerId());
        IPage<StmChannelPrice> pageList = new Page<>();
        if (!StringUtils.isEmpty(storeId) && !StringUtils.isEmpty(channelId)) {
            //先根据经销商查询数据
            stmChannelPrice.setChannelId(null);
            QueryWrapper<StmChannelPrice> queryWrapper = QueryGenerator.initQueryWrapper(stmChannelPrice, req.getParameterMap());
            Page<StmChannelPrice> page = new Page<StmChannelPrice>(pageNo, pageSize);
            pageList = stmChannelPriceService.page(page, queryWrapper);
            if (pageList == null || CollectionUtils.isEmpty(pageList.getRecords())) {
                //如果经销商没查到，在根据渠道查询
                stmChannelPrice.setStoreId(null);
                stmChannelPrice.setChannelId(channelId);
                queryWrapper = QueryGenerator.initQueryWrapper(stmChannelPrice, req.getParameterMap());
                pageList = stmChannelPriceService.page(page, queryWrapper);
            }
        } else if (StringUtils.isEmpty(storeId) && !StringUtils.isEmpty(channelId)) {
            //目前用在查询渠道的价格列表
            QueryWrapper<StmChannelPrice> queryWrapper = QueryGenerator.initQueryWrapper(stmChannelPrice, req.getParameterMap());
            Page<StmChannelPrice> page = new Page<StmChannelPrice>(pageNo, pageSize);
            pageList = stmChannelPriceService.page(page, queryWrapper);
        }

        List<String> skuCodeList = pageList.getRecords().stream().map(o -> o.getSkuCode()).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(skuCodeList)) {
            LambdaQueryWrapper<PmsProduct> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(PmsProduct::getSkuCode, skuCodeList).eq(PmsProduct::getDeleteStatus, 0);
            List<PmsProduct> productList = pmsProductService.list(wrapper);
            if (!CollectionUtils.isEmpty(productList)) {
                Map<String, PmsProduct> productMap = productList.stream().collect(Collectors.toMap(PmsProduct::getSkuCode, A -> A));
                pageList.getRecords().forEach(price -> {
                    if (productMap.get(price.getSkuCode()) != null) {
                        price.setProductName(productMap.get(price.getSkuCode()).getName());
                    }
                });
            }
        }
        return Result.ok(pageList);
    }

    @AutoLog(value = "经销商价格表-查询渠道价格列表")
    @ApiOperation(value = "经销商价格表-分页列表查询", notes = "经销商价格表-分页列表查询")
    @GetMapping(value = "/channelPriceList")
    public Result<?> queryChannelPriceList(StmChannelPrice stmChannelPrice,
                                           @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                           @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                           HttpServletRequest req) {

        QueryWrapper<StmChannelPrice> queryWrapper = getChannelPriceWrapper(stmChannelPrice);

        Page<StmChannelPrice> page = new Page<StmChannelPrice>(pageNo, pageSize);
        IPage<StmChannelPrice> pageList = stmChannelPriceService.page(page, queryWrapper);

        pageList.setRecords(setChannelPrice(pageList.getRecords()));

        return Result.ok(pageList);
    }

    /**
     * 返回查询渠道价格的QueryWrapper
     */
    private QueryWrapper<StmChannelPrice> getChannelPriceWrapper(StmChannelPrice stmChannelPrice) {

        List<String> searchSkuCodeList = new ArrayList<>();
        List<PmsProduct> searchProductNameList = new ArrayList<>();
        //如果界面上有输入产品名称进行搜索，先到产品表根据名称获取到物料编码，然后在产品价格表中增加skuCode的查询条件
        if (!StringUtils.isEmpty(stmChannelPrice.getProductName())) {
            searchProductNameList = productService.getProductListByProductName(stmChannelPrice.getProductName());
            if (!CollectionUtils.isEmpty(searchProductNameList)) {
                searchSkuCodeList = searchProductNameList.stream().map(o -> o.getSkuCode()).collect(Collectors.toList());
                //因为表中有这个字段，没有值，所以不清空这个字段，会导致查询这个字段
                stmChannelPrice.setProductName(null);
            }
        }

        QueryWrapper<StmChannelPrice> queryWrapper = QueryGenerator.initQueryWrapper(stmChannelPrice, null);
        queryWrapper.ne("channel_id", "").eq("status", 1);
        if (!CollectionUtils.isEmpty(searchSkuCodeList)) {
            queryWrapper.in("sku_code", searchSkuCodeList);
        }
        queryWrapper.orderByAsc("channel_id");

        return queryWrapper;
    }

    //设置渠道价格里面的值
    private List<StmChannelPrice> setChannelPrice(List<StmChannelPrice> channelPriceList) {

        if (CollectionUtils.isEmpty(channelPriceList)) {
            return channelPriceList;
        }
        List<String> skuCodeList = channelPriceList.stream().map(o -> o.getSkuCode()).collect(Collectors.toList());
        LambdaQueryWrapper<PmsProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(PmsProduct::getSkuCode, skuCodeList).eq(PmsProduct::getDeleteStatus, 0);
        List<PmsProduct> productList = pmsProductService.list(wrapper);

        List<String> channelIds = channelPriceList.stream().map(o -> o.getChannelId()).collect(Collectors.toList());
        List<StmChannelInfo> channelInfoList = stmChannelInfoService.getByChannelIds(channelIds);
        if (!CollectionUtils.isEmpty(channelInfoList)) {
            Map<String, StmChannelInfo> channelInfoMap = channelInfoList.stream().collect(Collectors.toMap(StmChannelInfo::getChannelId, A -> A));
            channelPriceList.forEach(price -> {
                if (channelInfoMap.get(price.getChannelId()) != null) {
                    price.setChannelName(channelInfoMap.get(price.getChannelId()).getName());
                }
            });
        }

        if (!CollectionUtils.isEmpty(productList)) {
            Map<String, PmsProduct> productMap = productList.stream().collect(Collectors.toMap(PmsProduct::getSkuCode, A -> A));
            channelPriceList.forEach(price -> {
                PmsProduct product = productMap.get(price.getSkuCode());
                if (product != null) {
                    price.setProductName(product.getName());
                    price.setBoxUnit(product.getSkuSpec() + product.getUnit() + "/" + product.getSkuUnit());
                }
            });
        }

        return channelPriceList;
    }


    /**
     * 添加
     *
     * @param stmChannelPrice
     * @return
     */
    @AutoLog(value = "经销商价格表-添加")
    @ApiOperation(value = "经销商价格表-添加", notes = "经销商价格表-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody StmChannelPrice stmChannelPrice) {

        stmChannelPrice.setPartnerId(4100L);
        stmChannelPriceService.save(stmChannelPrice);
        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     *
     * @param stmChannelPrice
     * @return
     */
    @AutoLog(value = "经销商价格表-编辑")
    @ApiOperation(value = "经销商价格表-编辑", notes = "经销商价格表-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody StmChannelPrice stmChannelPrice) {
        stmChannelPriceService.updateById(stmChannelPrice);
        return Result.ok("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "经销商价格表-通过id删除")
    @ApiOperation(value = "经销商价格表-通过id删除", notes = "经销商价格表-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {

        stmChannelPriceService.deleteId(id);
        return Result.ok("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "经销商价格表-批量删除")
    @ApiOperation(value = "经销商价格表-批量删除", notes = "经销商价格表-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.stmChannelPriceService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.ok("批量删除成功！");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "经销商价格表-通过id查询")
    @ApiOperation(value = "经销商价格表-通过id查询", notes = "经销商价格表-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        StmChannelPrice stmChannelPrice = stmChannelPriceService.getById(id);
        return Result.ok(stmChannelPrice);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param stmChannelPrice
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, StmChannelPrice stmChannelPrice) {

        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        QueryWrapper<StmChannelPrice> queryWrapper = getChannelPriceWrapper(stmChannelPrice);
        List<StmChannelPrice> channelPriceList = stmChannelPriceService.list(queryWrapper);
        channelPriceList = setChannelPrice(channelPriceList);

        List<StmChannelPriceExcel> excelList = new ArrayList<>();
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        channelPriceList.forEach(o -> {
            StmChannelPriceExcel channelPriceExcel = new StmChannelPriceExcel();
            BeanUtils.copyProperties(o, channelPriceExcel);
            channelPriceExcel.setPrice(decimalFormat.format(o.getPrice()));
            excelList.add(channelPriceExcel);
        });

        //Step.3 调用AutoPoi导出Excel
        ModelAndView mv = new ModelAndView(new EntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, "渠道价格列表");
        mv.addObject(NormalExcelConstants.CLASS, StmChannelPriceExcel.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("渠道价格列表", "导出人:" + sysUser.getRealname(), "渠道价格列表"));
        mv.addObject(NormalExcelConstants.DATA_LIST, excelList);
        return mv;

    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    @ApiOperation(value = "经销商价格表-通过id查询", notes = "经销商价格表-通过id查询")
    @PermitAll
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return stmChannelPriceService.importExcel(request, response, StmChannelPrice.class);
    }

}
